/**
*  \file sched.c
*
*  \brief Scheduler for windows architecture.
*
*  \author Michael J. Hohmann  <michael.hohmann@linde-mh.de>
*
*
*/

/*===============================================[ private includes  ]================================================*/
#include "sched.h"
#include "../assertor/assertor.h"
#include "grits.h"
#include <windows.h>

/*===============================================[ private defines   ]================================================*/
#define SCHEDULER_TIME_SLICES_MAX U16_CONST( 4 )

/*===============================================[ private datatypes ]================================================*/

/** Private variables */
struct sched_private
{
    struct grits_time_slice time_slices[ SCHEDULER_TIME_SLICES_MAX ];
	LARGE_INTEGER frequency;        /* ticks per second */
    LARGE_INTEGER starttime;        /* ticks */
};


/*===============================================[ private variables ]================================================*/
static struct sched_private sched;

/*===============================================[ private functions ]================================================*/
static U32 sched_get_os_time(void);
/*===============================================[ inline functions  ]================================================*/

/*===============================================[ public functions  ]================================================*/
RC sched_initialize( void )
{
	memset( &sched, 0, sizeof( sched ) );

	QueryPerformanceFrequency(&sched.frequency);
	QueryPerformanceCounter(&sched.starttime);

	sched.time_slices[0].interval=1;
	sched.time_slices[1].interval=10;
	sched.time_slices[2].interval=100;
	sched.time_slices[3].interval=0;

	grits_initialize( sched.time_slices, SCHEDULER_TIME_SLICES_MAX, 0 );

	return RC_SUCCESS;
}

void sched_run_idle(void)
{
	grits_process_time( sched.time_slices, SCHEDULER_TIME_SLICES_MAX, sched_get_os_time() );
}

struct tasklet_list* sched_get_slice_1ms( void )
{
	return &sched.time_slices[0].list;
}

struct tasklet_list* sched_get_slice_10ms( void )
{
	return &sched.time_slices[1].list;
}

struct tasklet_list* sched_get_slice_100ms( void )
{
	return &sched.time_slices[2].list;
}

struct tasklet_list* sched_get_slice_idle( void )
{
	return &sched.time_slices[3].list;
}

/*===============================================[ private functions ]================================================*/

static U32 sched_get_os_time(void)
{
   LARGE_INTEGER current_time;           /* ticks */
   double elapsedTime;
   QueryPerformanceCounter(&current_time);

   /* compute and print the elapsed time in millisec */
   elapsedTime = ( current_time.QuadPart - sched.starttime.QuadPart) * 1000.0 / sched.frequency.QuadPart;

   return (U32)elapsedTime;
}

/***********************************************************************************************************************
*                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
